package com.ruoyi.quartz.task;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.stock.domain.StockCurrent;
import com.ruoyi.stock.service.IStockCurrentService;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Component;

/**
 * 股票当前信息同步任务 同步来源：东方财富 URL： http://quote.eastmoney.com/center/gridlist.html#hs_a_board
 * 接口链接：http://7.push2.eastmoney.com/api/qt/clist/get?pn=1&pz=10000&po=1&np=1&ut=bd1d9ddb04089700cf9c27f6f7426281&fltt=2&invt=2&fid=f3&fs=m:0+t:6,m:0+t:80,m:1+t:2,m:1+t:23,m:0+t:81+s:2048&fields=f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f12,f13,f14,f15,f16,f17,f18,f20,f21,f23,f24,f25,f22,f11,f62,f128,f136,f115,f152&_=1636876369076
 * 接口字段解析： f12: 股票代码 f14：股票名称 f2：最新价 f3：涨跌幅 f4：涨跌额 f5：成交量（手） f6：成交额 f7：振幅 f8：换手率 f9：市盈率（动态）
 * f11：5分钟涨跌 f15：最高 f16：最低 f17：今开 f18：昨收 f20：总市值 f21：流通市值 f22：涨速 f23：市盈率 f24：60日涨跌幅 f25：年初至今涨跌幅
 */
@Component("stockCurrentInfoTask")
@Slf4j
@RequiredArgsConstructor
public class StockCurrentInfoTask {

  private static final String DC_URL =
      "http://7.push2.eastmoney.com/api/qt/clist/get?pn=1&pz=10000&po=1&np=1&ut=bd1d9ddb04089700cf9c27f6f7426281&fltt=2&invt=2&fid=f3&fs=m:0+t:6,m:0+t:80,m:1+t:2,m:1+t:23,m:0+t:81+s:2048&fields=f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f12,f13,f14,f15,f16,f17,f18,f20,f21,f23,f24,f25,f22,f11,f62,f128,f136,f115,f152&_=1636876369076";

  final IStockCurrentService stockCurrentService;

  private static ObjectMapper objectMapper;

  static {
    objectMapper = new ObjectMapper();
    objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
    objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
    objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    objectMapper.configure(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE, false);
    objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
    objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
    objectMapper.setDateFormat(new SimpleDateFormat("yyy-MM-dd HH:mm:ss"));
  }

  private static DateTimeFormatter yyyyMMdd = DateTimeFormatter.ofPattern("yyyyMMdd");

  public void run() {
    String result = HttpUtils.sendGet(DC_URL, null, null);
    JSONObject data = JSONObject.parseObject(result).getJSONObject("data");
    Integer total = data.getInteger("total");
    if (total > 0) {
      JSONArray jsonArray = data.getJSONArray("diff");
      List<StockCurrent> stockCurrentList =
          jsonArray.stream()
              .map(
                  json -> {
                    try {
                      JSONObject obj = (JSONObject) json;
                      obj.forEach(
                          (key, value) -> {
                            if ("-".equals(value)) {
                              obj.put(key, "");
                            }
                          });
                      StockCurrent stockCurrent =
                          objectMapper.readValue(obj.toString(), StockCurrent.class);
                      stockCurrent.setTradeDate(yyyyMMdd.format(LocalDate.now()));
                      stockCurrent.setClose(stockCurrent.getNow());
                      return stockCurrent;
                    } catch (JsonProcessingException e) {
                      log.error(e.getMessage(), e);
                    }
                    return null;
                  })
              .collect(Collectors.toList());

      if (CollectionUtils.isNotEmpty(stockCurrentList)) {
        stockCurrentService.deleteAll();
        stockCurrentService.insertBatch(
            stockCurrentList.stream()
                .filter(model -> model.getAmount() != null)
                .collect(Collectors.toList()));
      }
    }
  }
}
